<div class="content-section introduction">
    <div class="feature-intro">
        <h1>Dropdown</h1>
        <p>Dropdown is used to select an item from a list of options.</p>
    </div>
    <app-demoActions github="dropdown" stackblitz="dropdown-demo"></app-demoActions>
</div>

<div class="content-section implementation">
    <div class="card">
        <h5>Basic</h5>
        <p-dropdown [options]="cities" [(ngModel)]="selectedCity1" placeholder="Select a City" optionLabel="name" [showClear]="true"></p-dropdown>

        <h5>Editable</h5>
        <p-dropdown [options]="cities" [(ngModel)]="selectedCity2" [editable]="true" optionLabel="name"></p-dropdown>

        <h5>Group</h5>
        <p-dropdown [options]="groupedCities" [(ngModel)]="selectedCity3" placeholder="Select a City" [group]="true">
            <ng-template let-group pTemplate="group">
                <div class="flex align-items-center">
                    <img src="assets/showcase/images/demo/flag/flag_placeholder.png" [class]="'mr-2 flag flag-' + group.value" style="width: 20px"/>
                    <span>{{group.label}}</span>
                </div>
            </ng-template>
        </p-dropdown>

        <h5>Advanced with Templating, Filtering and Clear Icon</h5>
        <p-dropdown [options]="countries" [(ngModel)]="selectedCountry" optionLabel="name" [filter]="true" filterBy="name" [showClear]="true" placeholder="Select a Country">
            <ng-template pTemplate="selectedItem">
                <div class="country-item country-item-value" *ngIf="selectedCountry">
                    <img src="assets/showcase/images/demo/flag/flag_placeholder.png" [class]="'flag flag-' + selectedCountry.code.toLowerCase()" />
                    <div>{{selectedCountry.name}}</div>
                </div>
            </ng-template>
            <ng-template let-country pTemplate="item">
                <div class="country-item">
                    <img src="assets/showcase/images/demo/flag/flag_placeholder.png" [class]="'flag flag-' + country.code.toLowerCase()" />
                    <div>{{country.name}}</div>
                </div>
            </ng-template>
        </p-dropdown>

        <h5>Virtual Scroll (10000 Items)</h5>
        <p-dropdown [options]="items" [(ngModel)]="selectedItem1" placeholder="Select Item" [virtualScroll]="true" [virtualScrollItemSize]="38"></p-dropdown>

        <h5>Virtual Scroll (100000 Items) and Lazy</h5>
        <p-dropdown [options]="lazyItems" [(ngModel)]="selectedItem2" placeholder="Select Item" [virtualScroll]="true" [virtualScrollItemSize]="38" [lazy]="true" (onLazyLoad)="onLazyLoad($event)" [virtualScrollOptions]="{ showLoader: true, loading: loading, delay: 250 }">
            <ng-template pTemplate="loader" let-options="options">
                <div class="flex align-items-center py-2 px-3" style="height: 38px">
                    <p-skeleton [width]="options.even ? '60%' : '50%'" height="1rem"></p-skeleton>
                </div>
            </ng-template>
        </p-dropdown>
    </div>
</div>

<div class="content-section documentation">
    <p-tabView>
        <p-tabPanel header="Documentation">
            <h5>Import</h5>
<app-code lang="typescript" ngNonBindable ngPreserveWhitespaces>
import &#123;DropdownModule&#125; from 'primeng/dropdown';
</app-code>

            <h5>Getting Started</h5>
            <p>Dropdown requires a value to bind and a collection of options.</p>

<app-code lang="markup" ngNonBindable ngPreserveWhitespaces>
&lt;p-dropdown [options]="cities" [(ngModel)]="selectedCity" optionLabel="name"&gt;&lt;/p-dropdown&gt;
</app-code>

<app-code lang="typescript" ngNonBindable ngPreserveWhitespaces>
interface City &#123;
    name: string,
    code: string
&#125;

export class DropdownDemo &#123;

    cities: City[];

    selectedCity: City;

    constructor() &#123;
        this.cities = [
            &#123;name: 'New York', code: 'NY'&#125;,
            &#123;name: 'Rome', code: 'RM'&#125;,
            &#123;name: 'London', code: 'LDN'&#125;,
            &#123;name: 'Istanbul', code: 'IST'&#125;,
            &#123;name: 'Paris', code: 'PRS'&#125;
        ];
    &#125;

&#125;
</app-code>

                <h5>Value Binding</h5>
                <p>The option itself is bound to the model by default, use <i>optionValue</i> to customize the property to pass as the value.</p>
<app-code lang="markup" ngNonBindable ngPreserveWhitespaces>
&lt;p-dropdown [options]="cities" [(ngModel)]="selectedCityCode" optionLabel="name" optionValue="code"&gt;&lt;/p-dropdown&gt;
</app-code>

<app-code lang="typescript" ngNonBindable ngPreserveWhitespaces>
interface City &#123;
    name: string,
    code: string
&#125;

export class DropdownDemo &#123;

    cities: City[];

    selectedCityCode: string;

    constructor() &#123;
        this.cities = [
            &#123;name: 'New York', code: 'NY'&#125;,
            &#123;name: 'Rome', code: 'RM'&#125;,
            &#123;name: 'London', code: 'LDN'&#125;,
            &#123;name: 'Istanbul', code: 'IST'&#125;,
            &#123;name: 'Paris', code: 'PRS'&#125;
        ];
    &#125;

&#125;
</app-code>

                <h5>Disabled Options</h5>
                <p>Particular options can be prevented from selection using the <i>optionDisabled</i> property.</p>
<app-code lang="markup" ngNonBindable ngPreserveWhitespaces>
&lt;p-dropdown [options]="cities" [(ngModel)]="selectedCity" optionLabel="name" optionDisabled="inactive"&gt;&lt;/p-dropdown&gt;
</app-code>

<app-code lang="typescript" ngNonBindable ngPreserveWhitespaces>
interface City &#123;
    name: string,
    code: string
&#125;

export class DropdownDemo &#123;

    cities: City[];

    selectedCity: City;

    constructor() &#123;
        this.cities = [
            &#123;name: 'New York', code: 'NY', inactive: false&#125;,
            &#123;name: 'Rome', code: 'RM', inactive: true&#125;,
            &#123;name: 'London', code: 'LDN', inactive: false&#125;,
            &#123;name: 'Istanbul', code: 'IST', inactive: true&#125;,
            &#123;name: 'Paris', code: 'PRS', inactive: false&#125;
        ];
    &#125;

&#125;
</app-code>

            <h5>Model Driven Forms</h5>
            <p>Dropdown can be used in a model driven form as well.</p>
<app-code lang="markup" ngNonBindable ngPreserveWhitespaces>
&lt;p-dropdown [options]="cities" formControlName="selectedCity"&gt;&lt;/p-dropdown&gt;
</app-code>

            <h5>Custom Content</h5>
            <p>Both the selected option and the options list can be templated to provide customizated representation. Use
                <i>selectedItem</i> template to customize the selected label display and the <i>item</i> template to change the content of the options in the dropdown panel. In addition when grouping is enabled, <i>group</i> template is available
                to customize the option groups. All templates get the option instance as the default local template variable.
            </p>

<app-code lang="markup" ngNonBindable ngPreserveWhitespaces>
&lt;p-dropdown [options]="countries" [(ngModel)]="selectedCountry" optionLabel="name" filterBy="name" [showClear]="true" placeholder="Select a Country"&gt;
    &lt;ng-template pTemplate="filter" let-options="options"&gt;
        &lt;div class="flex p-3"&gt;
            &lt;div class="p-inputgroup" (click)="$event.stopPropagation()"&gt;
                &lt;span class="p-inputgroup-addon"&gt;&lt;i class="pi pi-search"&gt;&lt;/i&gt;&lt;/span&gt;
                &lt;input type="text" pInputText placeholder="Filter" [(ngModel)]="filterValue" (keyup)="options.filter($event)"&gt;
            &lt;/div&gt;
            &lt;button pButton icon="pi pi-times" class="ml-3" (click)="myResetFunction(options)"&gt;&lt;/button&gt;
        &lt;/div&gt;
    &lt;/ng-template&gt;
    &lt;ng-template pTemplate="selectedItem"&gt;
        &lt;div class="country-item country-item-value" *ngIf="selectedCountry"&gt;
            &lt;img src="assets/showcase/images/demo/flag/flag_placeholder.png" [class]="'flag flag-' + selectedCountry.code.toLowerCase()" /&gt;
            &lt;div&gt;&#123;&#123;selectedCountry.name&#125;&#125;&lt;/div&gt;
        &lt;/div&gt;
    &lt;/ng-template&gt;
    &lt;ng-template let-country pTemplate="item"&gt;
        &lt;div class="country-item"&gt;
            &lt;img src="assets/showcase/images/demo/flag/flag_placeholder.png" [class]="'flag flag-' + country.code.toLowerCase()" /&gt;
            &lt;div&gt;&#123;&#123;country.name&#125;&#125;&lt;/div&gt;
        &lt;/div&gt;
    &lt;/ng-template&gt;
&lt;/p-dropdown&gt;
</app-code>

<app-code lang="typescript" ngNonBindable ngPreserveWhitespaces>
import &#123;DropdownFilterOptions&#125; from 'primeng/dropdown';
...
interface City &#123;
    name: string,
    code: string
&#125;

export class DropdownDemo &#123;

    selectedCountry: Country;

    filterValue = '';

    constructor() &#123;
        this.countries = [
            &#123;name: 'Australia', code: 'AU'&#125;,
            &#123;name: 'Brazil', code: 'BR'&#125;,
            &#123;name: 'China', code: 'CN'&#125;,
            &#123;name: 'Egypt', code: 'EG'&#125;,
            &#123;name: 'France', code: 'FR'&#125;,
            &#123;name: 'Germany', code: 'DE'&#125;,
            &#123;name: 'India', code: 'IN'&#125;,
            &#123;name: 'Japan', code: 'JP'&#125;,
            &#123;name: 'Spain', code: 'ES'&#125;,
            &#123;name: 'United States', code: 'US'&#125;
        ];
    &#125;


    myResetFunction(options: DropdownFilterOptions) &#123;
        options.reset();
        this.filterValue = '';
    &#125;
&#125;
</app-code>

            <h5>Virtual Scrolling</h5>
            <p>VirtualScrolling is an efficient way of rendering the options by displaying a small subset of data in the viewport at any time. When dealing with huge number of options, it is suggested to enable VirtualScrolling
                to avoid performance issues. Usage is simple as setting virtualScroll property to true and defining virtualScrollItemSize to specify the height of an item. </p>
<app-code lang="markup" ngNonBindable ngPreserveWhitespaces>
&lt;p-dropdown [options]="cities" [virtualScroll]="true" [virtualScrollItemSize]="30"&gt;&lt;/p-dropdown&gt;
</app-code>

            <h5>Animation Configuration</h5>
            <p>Transition of the open and hide animations can be customized using the showTransitionOptions and hideTransitionOptions properties,
                example below disables the animations altogether.</p>
<app-code lang="markup" ngNonBindable ngPreserveWhitespaces>
&lt;p-dropdown [options]="cars" [(ngModel)]="selectedCar" [showTransitionOptions]="'0ms'" [hideTransitionOptions]="'0ms'"&gt;&lt;/p-dropdown&gt;
</app-code>

            <h5>Properties</h5>
            <div class="doc-tablewrapper">
                <table class="doc-table">
                    <thead>
                        <tr>
                            <th>Name</th>
                            <th>Type</th>
                            <th>Default</th>
                            <th>Description</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr>
                            <td>options</td>
                            <td>array</td>
                            <td>null</td>
                            <td>An array of objects to display as the available options.</td>
                        </tr>
                        <tr>
                            <td>optionLabel</td>
                            <td>string</td>
                            <td>label</td>
                            <td>Name of the label field of an option.</td>
                        </tr>
                        <tr>
                            <td>optionValue</td>
                            <td>string</td>
                            <td>value</td>
                            <td>Name of the value field of an option.</td>
                        </tr>
                        <tr>
                            <td>optionDisabled</td>
                            <td>string</td>
                            <td>disabled</td>
                            <td>Name of the disabled field of an option.</td>
                        </tr>
                        <tr>
                            <td>optionGroupLabel</td>
                            <td>string</td>
                            <td>label</td>
                            <td>Name of the label field of an option group.</td>
                        </tr>
                        <tr>
                            <td>optionGroupChildren</td>
                            <td>string</td>
                            <td>items</td>
                            <td>Name of the options field of an option group.</td>
                        </tr>
                        <tr>
                            <td>name</td>
                            <td>string</td>
                            <td>null</td>
                            <td>Name of the input element.</td>
                        </tr>
                        <tr>
                            <td>scrollHeight</td>
                            <td>string</td>
                            <td>200px</td>
                            <td>Height of the viewport in pixels, a scrollbar is defined if height of list exceeds this value.</td>
                        </tr>
                        <tr>
                            <td>style</td>
                            <td>string</td>
                            <td>null</td>
                            <td>Inline style of the element.</td>
                        </tr>
                        <tr>
                            <td>panelStyle</td>
                            <td>string</td>
                            <td>null</td>
                            <td>Inline style of the overlay panel element.</td>
                        </tr>
                        <tr>
                            <td>styleClass</td>
                            <td>string</td>
                            <td>null</td>
                            <td>Style class of the element.</td>
                        </tr>
                        <tr>
                            <td>panelStyleClass</td>
                            <td>string</td>
                            <td>null</td>
                            <td>Style class of the overlay panel element.</td>
                        </tr>
                        <tr>
                            <td>filter</td>
                            <td>boolean</td>
                            <td>false</td>
                            <td>When specified, displays an input field to filter the items on keyup.</td>
                        </tr>
                        <tr>
                            <td>filterValue</td>
                            <td>string</td>
                            <td>null</td>
                            <td>When specified, filter displays with this value.</td>
                        </tr>
                        <tr>
                            <td>filterBy</td>
                            <td>string</td>
                            <td>null</td>
                            <td>When filtering is enabled, filterBy decides which field or fields (comma separated) to search against.</td>
                        </tr>
                        <tr>
                            <td>filterMatchMode</td>
                            <td>string</td>
                            <td>contains</td>
                            <td>Defines how the items are filtered, valid values are "contains" (default) "startsWith", "endsWith", "equals", "notEquals", "in", "lt", "lte", "gt" and "gte".</td>
                        </tr>
                        <tr>
                            <td>filterPlaceholder</td>
                            <td>string</td>
                            <td>null</td>
                            <td>Placeholder text to show when filter input is empty.</td>
                        </tr>
                        <tr>
                            <td>filterLocale</td>
                            <td>string</td>
                            <td>undefined</td>
                            <td>Locale to use in filtering. The default locale is the host environment's current locale.</td>
                        </tr>
                        <tr>
                            <td>required</td>
                            <td>boolean</td>
                            <td>false</td>
                            <td>When present, it specifies that an input field must be filled out before submitting the form.</td>
                        </tr>
                        <tr>
                            <td>disabled</td>
                            <td>boolean</td>
                            <td>false</td>
                            <td>When present, it specifies that the component should be disabled.</td>
                        </tr>
                        <tr>
                            <td>readonly</td>
                            <td>boolean</td>
                            <td>false</td>
                            <td>When present, it specifies that the component cannot be edited.</td>
                        </tr>
                        <tr>
                            <td>emptyMessage</td>
                            <td>string</td>
                            <td>No records found.</td>
                            <td>Text to display when there is no data. Defaults to global value in i18n translation configuration.</td>
                        </tr>
                        <tr>
                            <td>emptyFilterMessage</td>
                            <td>string</td>
                            <td>No results found</td>
                            <td>Text to display when filtering does not return any results. Defaults to global value in i18n translation configuration.</td>
                        </tr>
                        <tr>
                            <td>ariaLabelledBy</td>
                            <td>string</td>
                            <td>null</td>
                            <td>Establishes relationships between the component and label(s) where its value should be one or more element IDs.</td>
                        </tr>
                        <tr>
                            <td>editable</td>
                            <td>boolean</td>
                            <td>false</td>
                            <td>When present, custom value instead of predefined options can be entered using the editable input field.</td>
                        </tr>
                        <tr>
                            <td>maxlength</td>
                            <td>number</td>
                            <td>null</td>
                            <td>Maximum number of character allows in the editable input field.</td>
                        </tr>
                        <tr>
                            <td>appendTo</td>
                            <td>any</td>
                            <td>null</td>
                            <td>Target element to attach the overlay, valid values are "body" or a local ng-template variable of another element (note: use binding with brackets for template variables, e.g. [appendTo]="mydiv" for a div element having #mydiv as variable name).</td>
                        </tr>
                        <tr>
                            <td>tabindex</td>
                            <td>number</td>
                            <td>null</td>
                            <td>Index of the element in tabbing order.</td>
                        </tr>
                        <tr>
                            <td>placeholder</td>
                            <td>string</td>
                            <td>null</td>
                            <td>Default text to display when no option is selected.</td>
                        </tr>
                        <tr>
                            <td>inputId</td>
                            <td>string</td>
                            <td>null</td>
                            <td>Identifier of the accessible input element.</td>
                        </tr>
                        <tr>
                            <td>dataKey</td>
                            <td>string</td>
                            <td>null</td>
                            <td>A property to uniquely identify a value in options.</td>
                        </tr>
                        <tr>
                            <td>autofocus</td>
                            <td>boolean</td>
                            <td>false</td>
                            <td>When present, it specifies that the component should automatically get focus on load.</td>
                        </tr>
                        <tr>
                            <td>autofocusFilter</td>
                            <td>boolean</td>
                            <td>false</td>
                            <td>Applies focus to the filter element when the overlay is shown.</td>
                        </tr>
                        <tr>
                            <td>resetFilterOnHide</td>
                            <td>boolean</td>
                            <td>false</td>
                            <td>Clears the filter value when hiding the dropdown.</td>
                        </tr>
                        <tr>
                            <td>dropdownIcon</td>
                            <td>string</td>
                            <td>pi pi-chevron-down</td>
                            <td>Icon class of the dropdown icon.</td>
                        </tr>
                        <tr>
                            <td>emptyFilterMessage</td>
                            <td>string</td>
                            <td>No results found</td>
                            <td>Text to display when filtering does not return any results.</td>
                        </tr>
                        <tr>
                            <td>autoDisplayFirst</td>
                            <td>boolean</td>
                            <td>true</td>
                            <td>Whether to display the first item as the label if no placeholder is defined and value is null.</td>
                        </tr>
                        <tr>
                            <td>group</td>
                            <td>boolean</td>
                            <td>false</td>
                            <td>Whether to display options as grouped when nested options are provided.</td>
                        </tr>
                        <tr>
                            <td>showClear</td>
                            <td>boolean</td>
                            <td>false</td>
                            <td>When enabled, a clear icon is displayed to clear the value.</td>
                        </tr>
                        <tr>
                            <td>baseZIndex</td>
                            <td>number</td>
                            <td>0</td>
                            <td>Base zIndex value to use in layering.</td>
                        </tr>
                        <tr>
                            <td>autoZIndex</td>
                            <td>boolean</td>
                            <td>true</td>
                            <td>Whether to automatically manage layering.</td>
                        </tr>
                        <tr>
                            <td>showTransitionOptions</td>
                            <td>string</td>
                            <td>.12s cubic-bezier(0, 0, 0.2, 1)</td>
                            <td>Transition options of the show animation.</td>
                        </tr>
                        <tr>
                            <td>hideTransitionOptions</td>
                            <td>string</td>
                            <td>.1s linear</td>
                            <td>Transition options of the hide animation.</td>
                        </tr>
                        <tr>
                            <td>ariaFilterLabel</td>
                            <td>string</td>
                            <td>null</td>
                            <td>Defines a string that labels the filter input.</td>
                        </tr>
                        <tr>
                            <td>ariaLabel</td>
                            <td>string</td>
                            <td>null</td>
                            <td>Used to define a string that autocomplete attribute the current element.</td>
                        </tr>
                        <tr>
                            <td>tooltip</td>
                            <td>any</td>
                            <td>null</td>
                            <td>Advisory information to display in a tooltip on hover.</td>
                        </tr>
                        <tr>
                            <td>tooltipStyleClass</td>
                            <td>string</td>
                            <td>null</td>
                            <td>Style class of the tooltip.</td>
                        </tr>
                        <tr>
                            <td>tooltipPosition</td>
                            <td>string</td>
                            <td>top</td>
                            <td>Position of the tooltip, valid values are right, left, top and bottom.</td>
                        </tr>
                        <tr>
                            <td>tooltipPositionStyle</td>
                            <td>string</td>
                            <td>absolute</td>
                            <td>Type of CSS position.</td>
                        </tr>
                        <tr>
                            <td>virtualScroll</td>
                            <td>boolean</td>
                            <td>false</td>
                            <td>Whether the data should be loaded on demand during scroll.</td>
                        </tr>
                        <tr>
                            <td>virtualScrollItemSize</td>
                            <td>number</td>
                            <td>null</td>
                            <td>Height of an item in the list for VirtualScrolling.</td>
                        </tr>
                        <tr>
                            <td>virtualScrollOptions</td>
                            <td>ScrollerOptions</td>
                            <td>false</td>
                            <td>Whether to use the scroller feature. The properties of <a href="#" [routerLink]="['/theming']">scroller</a> component can be used like an object in it.</td>
                        </tr>
                        <tr>
                            <td>lazy</td>
                            <td>boolean</td>
                            <td>false</td>
                            <td>Defines if data is loaded and interacted with in lazy manner.</td>
                        </tr>
                    </tbody>
                </table>
            </div>

            <h5>Events</h5>
            <div class="doc-tablewrapper">
                <table class="doc-table">
                    <thead>
                    <tr>
                        <th>Name</th>
                        <th>Parameters</th>
                        <th>Description</th>
                    </tr>
                    </thead>
                    <tbody>
                        <tr>
                            <td>onClick</td>
                            <td>event: Click event</td>
                            <td>Callback to invoke when component is clicked.</td>
                        </tr>
                        <tr>
                            <td>onChange</td>
                            <td>event.originalEvent: Browser event<br />
                                event.value: Selected option value
                            </td>
                            <td>Callback to invoke when value of dropdown changes.</td>
                        </tr>
                        <tr>
                            <td>onFilter</td>
                            <td>event.originalEvent: Browser event <br />
                                event.filter: Filter value used in filtering.</td>
                            <td>Callback to invoke when data is filtered.</td>
                        </tr>
                        <tr>
                            <td>onFocus</td>
                            <td>event: Browser event</td>
                            <td>Callback to invoke when dropdown gets focus.</td>
                        </tr>
                        <tr>
                            <td>onBlur</td>
                            <td>event: Browser event</td>
                            <td>Callback to invoke when dropdown loses focus.</td>
                        </tr>
                        <tr>
                            <td>onShow</td>
                            <td>event: Animation event</td>
                            <td>Callback to invoke when dropdown overlay gets visible.</td>
                        </tr>
                        <tr>
                            <td>onHide</td>
                            <td>event: Animation event</td>
                            <td>Callback to invoke when dropdown overlay gets hidden.</td>
                        </tr>
                        <tr>
                            <td>onClear</td>
                            <td>event: Animation event</td>
                            <td>Callback to invoke when dropdown clears the value.</td>
                        </tr>
                        <tr>
                            <td>onLazyLoad</td>
                            <td>event.first: First index of the new data range to be loaded.<br/>
                                event.last: Last index of the new data range to be loaded.
                            </td>
                            <td>Callback to invoke in lazy mode to load new data.</td>
                        </tr>
                    </tbody>
                </table>
            </div>

            <h5>Methods</h5>
            <div class="doc-tablewrapper">
                <table class="doc-table">
                    <thead>
                        <tr>
                            <th>Name</th>
                            <th>Parameters</th>
                            <th>Description</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr>
                            <td>resetFilter</td>
                            <td>-</td>
                            <td>Resets filtering.</td>
                        </tr>
                        <tr>
                            <td>focus</td>
                            <td>-</td>
                            <td>Applies focus.</td>
                        </tr>
                        <tr>
                            <td>show</td>
                            <td>-</td>
                            <td>Displays the panel.</td>
                        </tr>
                        <tr>
                            <td>hide</td>
                            <td>-</td>
                            <td>Hides the panel.</td>
                        </tr>
                    </tbody>
                </table>
            </div>

            <h5>Templates</h5>
            <div class="doc-tablewrapper">
                <table class="doc-table">
                    <thead>
                        <tr>
                            <th>Name</th>
                            <th>Parameters</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr>
                            <td>item</td>
                            <td>$implicit: Data of the option</td>
                        </tr>
                        <tr>
                            <td>group</td>
                            <td>$implicit: Group option</td>
                        </tr>
                        <tr>
                            <td>selectedItem</td>
                            <td>$implicit: value</td>
                        </tr>
                        <tr>
                            <td>header</td>
                            <td>-</td>
                        </tr>
                        <tr>
                            <td>filter</td>
                            <td>options.filter: Callback to filter data by the value param<br />
                                options.reset: Resets the filter.
                            </td>
                        </tr>
                        <tr>
                            <td>empty</td>
                            <td>-</td>
                        </tr>
                        <tr>
                            <td>emptyfilter</td>
                            <td>-</td>
                        </tr>
                        <tr>
                            <td>footer</td>
                            <td>-</td>
                        </tr>
                        <tr>
                            <td>loader</td>
                            <td>options: Options of the scroller on loading. *This template can be used with virtualScroll.</td>
                        </tr>
                    </tbody>
                </table>
            </div>

            <h5>Styling</h5>
            <p>Following is the list of structural style classes, for theming classes visit <a href="#" [routerLink]="['/theming']">theming page</a>.</p>
            <div class="doc-tablewrapper">
                <table class="doc-table">
                    <thead>
                        <tr>
                            <th>Name</th>
                            <th>Element</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr>
                            <td>p-dropdown</td>
                            <td>Container element.</td>
                        </tr>
                        <tr>
                            <td>p-dropdown-clearable</td>
                            <td>Container element when showClear is on.</td>
                        </tr>
                        <tr>
                            <td>p-dropdown-label</td>
                            <td>Element to display label of selected option.</td>
                        </tr>
                        <tr>
                            <td>p-dropdown-trigger</td>
                            <td>Icon element.</td>
                        </tr>
                        <tr>
                            <td>p-dropdown-panel</td>
                            <td>Icon element.</td>
                        </tr>
                        <tr>
                            <td>p-dropdown-items-wrapper</td>
                            <td>Wrapper element of items list.</td>
                        </tr>
                        <tr>
                            <td>p-dropdown-items</td>
                            <td>List element of items.</td>
                        </tr>
                        <tr>
                            <td>p-dropdown-item</td>
                            <td>An item in the list.</td>
                        </tr>
                        <tr>
                            <td>p-dropdown-filter-container</td>
                            <td>Container of filter input.</td>
                        </tr>
                        <tr>
                            <td>p-dropdown-filter</td>
                            <td>Filter element.</td>
                        </tr>
                        <tr>
                            <td>p-dropdown-open</td>
                            <td>Container element when overlay is visible.</td>
                        </tr>
                    </tbody>
                </table>
            </div>

            <h5>Dependencies</h5>
            <p>None.</p>
        </p-tabPanel>

        <p-tabPanel header="Source">
            <a href="https://github.com/primefaces/primeng/tree/master/src/app/showcase/components/dropdown" class="btn-viewsource" target="_blank">
                <span>View on GitHub</span>
            </a>
            <a href="https://stackblitz.com/edit/primeng-dropdown-demo" class="btn-viewsource" style="margin-left: .5em;" target="_blank">
                <span>Edit in StackBlitz</span>
            </a>
<app-code lang="markup" ngNonBindable ngPreserveWhitespaces>
&lt;div class="card"&gt;
    &lt;h5&gt;Basic&lt;/h5&gt;
    &lt;p-dropdown [options]="cities" [(ngModel)]="selectedCity1" placeholder="Select a City" optionLabel="name" [showClear]="true"&gt;&lt;/p-dropdown&gt;

    &lt;h5&gt;Editable&lt;/h5&gt;
    &lt;p-dropdown [options]="cities" [(ngModel)]="selectedCity2" [editable]="true" optionLabel="name"&gt;&lt;/p-dropdown&gt;

    &lt;h5&gt;Group&lt;/h5&gt;
    &lt;p-dropdown [options]="groupedCities" [(ngModel)]="selectedCity3" placeholder="Select a City" [group]="true"&gt;
        &lt;ng-template let-group pTemplate="group"&gt;
            &lt;div class="flex align-items-center"&gt;
                &lt;img src="assets/showcase/images/demo/flag/flag_placeholder.png" [class]="'mr-2 flag flag-' + group.value" style="width: 20px"/&gt;
                &lt;span&gt;&#123;&#123;group.label&#125;&#125;&lt;/span&gt;
            &lt;/div&gt;
        &lt;/ng-template&gt;
    &lt;/p-dropdown&gt;

    &lt;h5&gt;Advanced with Templating, Filtering and Clear Icon&lt;/h5&gt;
    &lt;p-dropdown [options]="countries" [(ngModel)]="selectedCountry" optionLabel="name" [filter]="true" filterBy="name" [showClear]="true" placeholder="Select a Country"&gt;
        &lt;ng-template pTemplate="selectedItem"&gt;
            &lt;div class="country-item country-item-value" *ngIf="selectedCountry"&gt;
                &lt;img src="assets/showcase/images/demo/flag/flag_placeholder.png" [class]="'flag flag-' + selectedCountry.code.toLowerCase()" /&gt;
                &lt;div&gt;&#123;&#123;selectedCountry.name&#125;&#125;&lt;/div&gt;
            &lt;/div&gt;
        &lt;/ng-template&gt;
        &lt;ng-template let-country pTemplate="item"&gt;
            &lt;div class="country-item"&gt;
                &lt;img src="assets/showcase/images/demo/flag/flag_placeholder.png" [class]="'flag flag-' + country.code.toLowerCase()" /&gt;
                &lt;div&gt;&#123;&#123;country.name&#125;&#125;&lt;/div&gt;
            &lt;/div&gt;
        &lt;/ng-template&gt;
    &lt;/p-dropdown&gt;

    &lt;h5&gt;Virtual Scroll (10000 Items)&lt;/h5&gt;
    &lt;p-dropdown [options]="items" [(ngModel)]="selectedItem1" placeholder="Select Item" [virtualScroll]="true" [virtualScrollItemSize]="38"&gt;&lt;/p-dropdown&gt;

    &lt;h5&gt;Virtual Scroll (100000 Items) and Lazy&lt;/h5&gt;
    &lt;p-dropdown [options]="lazyItems" [(ngModel)]="selectedItem2" placeholder="Select Item" [virtualScroll]="true" [virtualScrollItemSize]="38" [lazy]="true" (onLazyLoad)="onLazyLoad($event)" [virtualScrollOptions]="&#123; showLoader: true, loading: loading, delay: 250 &#125;"&gt;
        &lt;ng-template pTemplate="loader" let-options="options"&gt;
            &lt;div class="flex align-items-center py-2 px-3" style="height: 38px"&gt;
                &lt;p-skeleton [width]="options.even ? '60%' : '50%'" height="1rem"&gt;&lt;/p-skeleton&gt;
            &lt;/div&gt;
        &lt;/ng-template&gt;
    &lt;/p-dropdown&gt;
&lt;/div&gt;
</app-code>

<app-code lang="typescript" ngNonBindable ngPreserveWhitespaces>
export class DropdownDemo &#123;

    cities: City[];

    selectedCity1: City;

    selectedCity2: City;

    selectedCity3: string;

    selectedCountry: string;

    countries: any[];

    groupedCities: SelectItemGroup[];

    items: SelectItem[];

    lazyItems: SelectItem[];

    selectedItem1: string;

    selectedItem2: string;

    loading: boolean = false;

    loadLazyTimeout: any;

    constructor() &#123;
        this.items = [];
        for (let i = 0; i &lt; 10000; i++) &#123;
            this.items.push(&#123;label: 'Item ' + i, value: 'Item ' + i&#125;);
        &#125;

        this.cities = [
            &#123;name: 'New York', code: 'NY'&#125;,
            &#123;name: 'Rome', code: 'RM'&#125;,
            &#123;name: 'London', code: 'LDN'&#125;,
            &#123;name: 'Istanbul', code: 'IST'&#125;,
            &#123;name: 'Paris', code: 'PRS'&#125;
        ];

        this.groupedCities = [
            &#123;
                label: 'Germany', value: 'de',
                items: [
                    &#123;label: 'Berlin', value: 'Berlin'&#125;,
                    &#123;label: 'Frankfurt', value: 'Frankfurt'&#125;,
                    &#123;label: 'Hamburg', value: 'Hamburg'&#125;,
                    &#123;label: 'Munich', value: 'Munich'&#125;
                ]
            &#125;,
            &#123;
                label: 'USA', value: 'us',
                items: [
                    &#123;label: 'Chicago', value: 'Chicago'&#125;,
                    &#123;label: 'Los Angeles', value: 'Los Angeles'&#125;,
                    &#123;label: 'New York', value: 'New York'&#125;,
                    &#123;label: 'San Francisco', value: 'San Francisco'&#125;
                ]
            &#125;,
            &#123;
                label: 'Japan', value: 'jp',
                items: [
                    &#123;label: 'Kyoto', value: 'Kyoto'&#125;,
                    &#123;label: 'Osaka', value: 'Osaka'&#125;,
                    &#123;label: 'Tokyo', value: 'Tokyo'&#125;,
                    &#123;label: 'Yokohama', value: 'Yokohama'&#125;
                ]
            &#125;
        ];

        this.countries = [
            &#123;name: 'Australia', code: 'AU'&#125;,
            &#123;name: 'Brazil', code: 'BR'&#125;,
            &#123;name: 'China', code: 'CN'&#125;,
            &#123;name: 'Egypt', code: 'EG'&#125;,
            &#123;name: 'France', code: 'FR'&#125;,
            &#123;name: 'Germany', code: 'DE'&#125;,
            &#123;name: 'India', code: 'IN'&#125;,
            &#123;name: 'Japan', code: 'JP'&#125;,
            &#123;name: 'Spain', code: 'ES'&#125;,
            &#123;name: 'United States', code: 'US'&#125;
        ];

        this.lazyItems = Array.from(&#123; length: 100000 &#125;);
    &#125;

    onLazyLoad(event) &#123;
        this.loading = true;

        if (this.loadLazyTimeout) &#123;
            clearTimeout(this.loadLazyTimeout);
        &#125;

        //imitate delay of a backend call
        this.loadLazyTimeout = setTimeout(() =&gt; &#123;
            const &#123; first, last &#125; = event;
            const lazyItems = [...this.lazyItems];

            for (let i = first; i &lt; last; i++) &#123;
                lazyItems[i] = &#123; label: `Item #$&#123;i&#125;`, value: i &#125;;
            &#125;

            this.lazyItems = lazyItems;
            this.loading = false;
        &#125;, Math.random() * 1000 + 250);
    &#125;
&#125;
</app-code>

<app-code lang="css" ngNonBindable ngPreserveWhitespaces>
:host ::ng-deep .p-dropdown &#123;
    width: 14rem;
&#125;

.country-item-value &#123;
    img.flag &#123;
        width: 17px;
    &#125;
&#125;

p-skeleton &#123;
    width: 100%;
&#125;
</app-code>

<app-code lang="typescript" ngNonBindable ngPreserveWhitespaces>
@Injectable()
export class CountryService &#123;

    constructor(private http: Http) &#123;&#125;

    getCountries() &#123;
        return this.http.get('showcase/resources/data/countries.json')
                    .toPromise()
                    .then(res => &lt;any[]&gt; res.json().data)
                    .then(data => &#123; return data; &#125;);
    &#125;
&#125;
</app-code>
        </p-tabPanel>

        <p-tabPanel header="StackBlitz">
            <ng-template pTemplate="content">
                <iframe src="https://stackblitz.com/edit/primeng-dropdown-demo?embed=1" style="width: 100%; height: 768px; border: none;"></iframe>
            </ng-template>
        </p-tabPanel>
    </p-tabView>
</div>
